import type { ContainerProcessor, BlockProcessor, Row, PreBlock, PreBlockquote } from '../types';

const isContainerBegin = ({ value }: Row) => value.startsWith('>');

/**
 * ```
 *                                      row.value.startsWith('>') or
 *                     else           startWithParagraphContinuationText
 *       +---<--------------------------<--   -->---------->--+
 *       |                                  Y                 |
 *       |                                  |                 |
 *       V     row.value.startsWith('>')    |                 |
 * INIT(0) -------------------------------> BLOCKQUOTE(1) <---+
 *   |   ^                                  /
 *   |    \                                / not a row
 *   |     + --<-----------------------<--+
 *   〧
 *
 * ```
 */
const makeBlockquoteProcessor = (BlockProcessors: BlockProcessor[]): ContainerProcessor => {
  const startWithParagraphContinuationText = (row: Row): boolean => {
    for (const processor of BlockProcessors) {
      if (processor.isBlockBegin(row)) {
        return false;
      }
    }
    return true;
  };

  return {
    isContainerBegin,
    process: (pbs) => {
      const result: PreBlock[] = [];
      let state = 0;
      for (const block of pbs) {
        const { type } = block;
        switch (state) {
          case 0: {
            if (type === 'row') {
              if (isContainerBegin(block)) {
                state = 1;
                result.push({ type: 'blockquote', blocks: [block] });
              } else {
                result.push(block);
              }
            } else {
              result.push(block);
            }
            break;
          }
          case 1: {
            if (type === 'row') {
              if (isContainerBegin(block) || startWithParagraphContinuationText(block)) {
                (result[result.length - 1] as PreBlockquote).blocks.push(block);
              } else {
                result.push(block);
                state = 0;
              }
            } else {
              result.push(block);
              state = 0;
            }
            break;
          }
        }
      }
      return result;
    },
  };
};

export default {
  makeProcessor: makeBlockquoteProcessor,
};
